﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.ComponentModel;
using System.Collections.Generic;

namespace G.Reader.API
{
    public class FileUtil
    {
        private const string URL = "http://dagehaoshuang.31.cvod.net/EncodingConvert.ashx";
        int bytesRead;
        bool isFisrt = true;
        byte[] transferBuffer = new byte[102400];//一次上传 100KB
        System.IO.Stream tempStream;
        string fileName;
        public event ProgressChangedEventHandler DownloadProgressChanged;
        public event EventHandler DownloadComplete;
        public event EventHandler Error;
        public FileUtil()
        {
        }

        #region 上传
        public event ProgressChangedEventHandler UploadProgressChanged;
        public event EventHandler UploadComplete;
        public void UploadFile(System.IO.Stream fileStream, string filename)
        {
            isFisrt = true;
            tempStream = fileStream;
            fileName = filename;
            tempStream.Seek(0, System.IO.SeekOrigin.Begin);
            UploadFile(string.Empty);
            isFisrt = false;
        }

        private void UploadFile(string s)
        {
            if (!isFisrt)
            {
                if (UploadProgressChanged != null)
                {
                    UploadProgressChanged(this, new ProgressChangedEventArgs((int)(tempStream.Position * 100 / tempStream.Length), null));
                }
            }
            bytesRead = tempStream.Read(transferBuffer, 0, transferBuffer.Length);
            if (bytesRead != 0)
            {

                UploadFile(UploadFile);
            }
            else
            {
                if (UploadComplete != null)
                    UploadComplete(this, EventArgs.Empty);
            }
        }

        private void UploadFile(Action<string> callback)
        {
            Dictionary<string, string> headers = new Dictionary<string, string>();
            headers["method"] = "upload";
            headers["filetype"] = "book";
            headers["filename"] = fileName;
            headers["isfirst"] = isFisrt.ToString();
            DoPost((stream) =>
            {
                using (var reader = new System.IO.StreamReader(stream))
                {
                    var str = reader.ReadToEnd();
                    callback(str);
                }
            }, headers);
        }
        #endregion
        public void Cancel()
        {
            if (request != null)
                request.Abort();
        }
        HttpWebRequest request;
        private void DoPost(Action<System.IO.Stream> callback, Dictionary<string, string> headers = null)
        {
            request = HttpWebRequest.Create(URL) as HttpWebRequest;
            if (headers != null)
            {
                foreach (var item in headers)
                {
                    request.Headers[item.Key] = HttpUtility.UrlEncode(item.Value);
                }
            }
            request.Method = "POST";
            request.BeginGetRequestStream((i1) =>
              {
                  try
                  {
                      var stream = request.EndGetRequestStream(i1);
                      stream.Write(transferBuffer, 0, bytesRead);
                      stream.Flush();
                      stream.Close();
                      request.BeginGetResponse((i2) =>
                      {
                          try
                          {

                              var response = request.EndGetResponse(i2);
                              callback(response.GetResponseStream());
                          }
                          catch (WebException ex)
                          {
                              OnError(ex);
                          }
                      }, null);
                  }
                  catch (WebException ex)
                  {
                      OnError(ex);
                  }
              }, null);

        }
        #region 转换编码

        private void OnError(Exception ex)
        {
            if (Error != null)
                Error(this, EventArgs.Empty);
        }
        public event ProgressChangedEventHandler ChangeEncodingProgressChanged;
        public event ChangedEncodingCompleteHandel ChangeEncodingComplete;
        private System.IO.Stream changedEncodingStream;//存放已转换编码的流
        public void ChangeEncoding(System.IO.Stream fileStream)
        {

            isFisrt = true;
            tempStream = fileStream;
            tempStream.Seek(0, System.IO.SeekOrigin.Begin);
            changedEncodingStream = new System.IO.MemoryStream();
            ChangeEncoding(string.Empty);
            isFisrt = false;
        }

        private void ChangeEncoding(string s)
        {
            if (!isFisrt)
            {
                if (ChangeEncodingProgressChanged != null)
                {
                    ChangeEncodingProgressChanged(this, new ProgressChangedEventArgs((int)(tempStream.Position * 100 / tempStream.Length), null));
                }
            }
            bytesRead = tempStream.Read(transferBuffer, 0, transferBuffer.Length);
            if (bytesRead != 0)
            {
                ChangeEncoding(ChangeEncoding);
            }
            else
            {
                changedEncodingStream.Seek(0, System.IO.SeekOrigin.Begin);
                if (ChangeEncodingComplete != null)
                    ChangeEncodingComplete(this, new ChangedEncodingCompleteArgs() { ChangedEncodingStream = changedEncodingStream });
            }
        }
        private void ChangeEncoding(Action<string> callback)
        {
            Dictionary<string, string> headers = new Dictionary<string, string>();
            headers["method"] = "encoding";
            headers["encodingname"] = "utf-8";
            DoPost((stream) =>
            {
                stream.CopyTo(changedEncodingStream);
                callback(string.Empty);
            }, headers);
        }
        #endregion
    }
    public delegate void ChangedEncodingCompleteHandel(object sender, ChangedEncodingCompleteArgs e);
    public class ChangedEncodingCompleteArgs : EventArgs
    {
        public System.IO.Stream ChangedEncodingStream { get; internal set; }
    }
}
